#include "dualcanvasrenderer.h"
#include <QDebug>
#include <QGuiApplication>
#include <QPainter>
#include <QElapsedTimer>
#include <QMutexLocker>
#include <QCryptographicHash>
#include <cmath>
// === CanvasConfig实现 ===
DualCanvasRenderer::CanvasConfig::CanvasConfig()
    : displayDpi(96.0)
    , processingDpi(300.0)
    , pageSizeMM(DisplayCanvasCalculator::A4_WIDTH_MM, DisplayCanvasCalculator::A4_HEIGHT_MM)
    , useHighQualityScaling(true)
    , scalingMode(Qt::SmoothTransformation)
{
    // 自动获取当前显示器信息
    displayInfo = DisplayCanvasCalculator::getCurrentDisplayInfo();
    displayDpi = DisplayCanvasCalculator::getRecommendedDisplayDpi(displayInfo);
    displaySize = DisplayCanvasCalculator::calculateA4PhysicalSize(displayInfo);
}
QSize DualCanvasRenderer::CanvasConfig::calculatePhysicalCanvasSize() const
{
    // 物理画布尺寸基于显示器DPI，保持固定
    return DisplayCanvasCalculator::calculatePhysicalPixelSize(pageSizeMM, displayInfo);
}
QSize DualCanvasRenderer::CanvasConfig::calculateVirtualCanvasSize() const
{
    // 虚拟画布尺寸基于处理DPI，随DPI变化
    double widthPixels = (pageSizeMM.width() / DisplayCanvasCalculator::MM_PER_INCH) * processingDpi;
    double heightPixels = (pageSizeMM.height() / DisplayCanvasCalculator::MM_PER_INCH) * processingDpi;
    return QSize(qRound(widthPixels), qRound(heightPixels));
}
double DualCanvasRenderer::CanvasConfig::getScaleFactor() const
{
    QSize physicalSize = calculatePhysicalCanvasSize();
    QSize virtualSize = calculateVirtualCanvasSize();
    if (virtualSize.width() <= 0 || virtualSize.height() <= 0) {
        return 1.0;
    }
    // 使用较小的缩放比例以保持宽高比
    double scaleX = static_cast<double>(physicalSize.width()) / virtualSize.width();
    double scaleY = static_cast<double>(physicalSize.height()) / virtualSize.height();
    return qMin(scaleX, scaleY);
}
bool DualCanvasRenderer::CanvasConfig::isValid() const
{
    if (displayDpi <= 0 || processingDpi <= 0) {
        return false;
    }
    if (pageSizeMM.width() <= 0 || pageSizeMM.height() <= 0) {
        return false;
    }
    QSize physicalSize = calculatePhysicalCanvasSize();
    QSize virtualSize = calculateVirtualCanvasSize();
    return physicalSize.isValid() && virtualSize.isValid() &&
           physicalSize.width() > 0 && physicalSize.height() > 0 &&
           virtualSize.width() > 0 && virtualSize.height() > 0;
}
QString DualCanvasRenderer::CanvasConfig::getDebugInfo() const
{
    QString info;
    QTextStream stream(&info);
    stream << "=== DualCanvas配置信息 ===" << Qt::endl;
    stream << QString("显示DPI: %1").arg(displayDpi) << Qt::endl;
    stream << QString("处理DPI: %1").arg(processingDpi) << Qt::endl;
    stream << QString("页面尺寸: %1×%2mm").arg(pageSizeMM.width()).arg(pageSizeMM.height()) << Qt::endl;
    QSize physicalSize = calculatePhysicalCanvasSize();
    QSize virtualSize = calculateVirtualCanvasSize();
    stream << QString("物理画布: %1×%2像素").arg(physicalSize.width()).arg(physicalSize.height()) << Qt::endl;
    stream << QString("虚拟画布: %1×%2像素").arg(virtualSize.width()).arg(virtualSize.height()) << Qt::endl;
    stream << QString("缩放比例: %1").arg(getScaleFactor()) << Qt::endl;
    stream << QString("高质量缩放: %1").arg(useHighQualityScaling ? "是" : "否") << Qt::endl;
    return info;
}
// === DualCanvasRenderer实现 ===
DualCanvasRenderer::DualCanvasRenderer(QObject* parent)
    : QObject(parent)
    , m_configInitialized(false)
    , m_virtualCanvasCache(DEFAULT_CACHE_SIZE)
    , m_physicalCanvasCache(DEFAULT_CACHE_SIZE)
    , m_totalRenderTime(0)
    , m_renderCount(0)
{
    // 设置缓存最大内存限制
    qint64 maxCacheBytes = MAX_CACHE_MEMORY_MB * 1024 * 1024;
    m_virtualCanvasCache.setMaxCost(maxCacheBytes / 2);  // 虚拟画布缓存一半
    m_physicalCanvasCache.setMaxCost(maxCacheBytes / 2); // 物理画布缓存一半
}
DualCanvasRenderer::~DualCanvasRenderer()
{
    clearCache();
}
void DualCanvasRenderer::setCanvasConfig(const CanvasConfig& config)
{
    if (!config.isValid()) {
        return;
    }
    CanvasConfig oldConfig = m_config;
    m_config = config;
    m_configInitialized = true;
    // 如果关键配置发生变化，清除缓存
    if (!oldConfig.isValid() ||
        !qFuzzyCompare(oldConfig.processingDpi, config.processingDpi) ||
        !qFuzzyCompare(oldConfig.displayDpi, config.displayDpi) ||
        oldConfig.pageSizeMM != config.pageSizeMM) {
        clearCache();
    }
    emit configChanged(oldConfig, config);
}
const DualCanvasRenderer::CanvasConfig& DualCanvasRenderer::getCanvasConfig() const
{
    return m_config;
}
void DualCanvasRenderer::updateProcessingDpi(double newDpi)
{
    if (newDpi <= 0) {
        return;
    }
    if (!qFuzzyCompare(m_config.processingDpi, newDpi)) {
        m_config.processingDpi = newDpi;
        clearCacheForDpi(newDpi); // 只清除相关缓存
    }
}
void DualCanvasRenderer::autoConfigureForDisplay(QScreen* screen)
{
    CanvasConfig config;
    // 获取指定屏幕信息
    config.displayInfo = DisplayCanvasCalculator::getCurrentDisplayInfo(screen);
    config.displayDpi = DisplayCanvasCalculator::getRecommendedDisplayDpi(config.displayInfo);
    config.displaySize = DisplayCanvasCalculator::calculateA4PhysicalSize(config.displayInfo);
    // 保持现有的处理DPI（如果已设置）
    if (m_configInitialized) {
        config.processingDpi = m_config.processingDpi;
        config.useHighQualityScaling = m_config.useHighQualityScaling;
        config.scalingMode = m_config.scalingMode;
    }
    setCanvasConfig(config);
}
QImage DualCanvasRenderer::renderForDisplay(const RenderContext& context)
{
    if (!isConfigured()) {
        return QImage();
    }
    QElapsedTimer timer;
    timer.start();
    emit renderingStarted(context);
    // 获取或创建虚拟画布
    QImage virtualCanvas = getOrCreateVirtualCanvas(context);
    if (virtualCanvas.isNull()) {
        return QImage();
    }
    // 缩放到物理画布
    QImage physicalCanvas = scaleToPhysicalCanvas(virtualCanvas);
    qint64 renderTime = timer.elapsed();
    m_totalRenderTime += renderTime;
    m_renderCount++;
    emit renderingFinished(context, renderTime);
    return physicalCanvas;
}
QImage DualCanvasRenderer::renderForPDF(const RenderContext& context)
{
    if (!isConfigured()) {
        return QImage();
    }
    QElapsedTimer timer;
    timer.start();
    emit renderingStarted(context);
    // PDF导出直接使用虚拟画布（高分辨率）
    QImage virtualCanvas = getOrCreateVirtualCanvas(context);
    qint64 renderTime = timer.elapsed();
    m_totalRenderTime += renderTime;
    m_renderCount++;
    emit renderingFinished(context, renderTime);
    return virtualCanvas;
}
void DualCanvasRenderer::renderToPainter(QPainter* painter, const QRect& targetRect,
                                       const RenderContext& context, bool forcePhysicalCanvas)
{
    if (!painter || !isConfigured()) {
        return;
    }
    QImage canvas;
    if (forcePhysicalCanvas) {
        canvas = renderForDisplay(context);
    } else {
        canvas = renderForPDF(context);
    }
    if (!canvas.isNull()) {
        painter->drawImage(targetRect, canvas);
    }
}
QSize DualCanvasRenderer::getPhysicalCanvasSize() const
{
    return m_configInitialized ? m_config.calculatePhysicalCanvasSize() : QSize();
}
QSize DualCanvasRenderer::getVirtualCanvasSize() const
{
    return m_configInitialized ? m_config.calculateVirtualCanvasSize() : QSize();
}
double DualCanvasRenderer::getCurrentScaleFactor() const
{
    return m_configInitialized ? m_config.getScaleFactor() : 1.0;
}
bool DualCanvasRenderer::isConfigured() const
{
    return m_configInitialized && m_config.isValid();
}
void DualCanvasRenderer::clearCache()
{
    QMutexLocker locker(&m_cacheMutex);
    m_virtualCanvasCache.clear();
    m_physicalCanvasCache.clear();
}
void DualCanvasRenderer::clearCacheForDpi(double dpi)
{
    QMutexLocker locker(&m_cacheMutex);
    QString dpiPrefix = QString("dpi_%1_").arg(dpi);
    // 清除包含指定DPI的缓存项
    auto clearCacheWithPrefix = [&dpiPrefix](QCache<QString, QImage>& cache) {
        QStringList keysToRemove;
        // 注意：QCache不提供直接遍历键的方法，这里需要改进
        // 暂时清空整个缓存（简单实现）
        cache.clear();
    };
    clearCacheWithPrefix(m_virtualCanvasCache);
    clearCacheWithPrefix(m_physicalCanvasCache);
}
QString DualCanvasRenderer::getCacheStats() const
{
    QMutexLocker locker(&m_cacheMutex);
    QString stats;
    QTextStream stream(&stats);
    stream << "=== DualCanvas缓存统计 ===" << Qt::endl;
    stream << QString("虚拟画布缓存: %1项").arg(m_virtualCanvasCache.size()) << Qt::endl;
    stream << QString("物理画布缓存: %1项").arg(m_physicalCanvasCache.size()) << Qt::endl;
    stream << QString("总渲染次数: %1").arg(m_renderCount) << Qt::endl;
    stream << QString("总渲染时间: %1ms").arg(m_totalRenderTime) << Qt::endl;
    if (m_renderCount > 0) {
        stream << QString("平均渲染时间: %1ms").arg(m_totalRenderTime / m_renderCount) << Qt::endl;
    }
    return stats;
}
// === 私有方法实现 ===
QImage DualCanvasRenderer::getOrCreateVirtualCanvas(const RenderContext& context)
{
    QString cacheKey = generateCacheKey(context, m_config.processingDpi);
    // 尝试从缓存获取
    QImage cachedCanvas = getCachedCanvas(cacheKey);
    if (!cachedCanvas.isNull()) {
        return cachedCanvas;
    }
    // 创建新的虚拟画布
    QImage virtualCanvas = createVirtualCanvas(context);
    if (!virtualCanvas.isNull()) {
        setCachedCanvas(cacheKey, virtualCanvas);
    }
    return virtualCanvas;
}
QImage DualCanvasRenderer::scaleToPhysicalCanvas(const QImage& virtualCanvas)
{
    if (virtualCanvas.isNull()) {
        return QImage();
    }
    QSize physicalSize = m_config.calculatePhysicalCanvasSize();
    if (physicalSize == virtualCanvas.size()) {
        return virtualCanvas; // 无需缩放
    }
    Qt::TransformationMode mode = m_config.useHighQualityScaling ?
                                 m_config.scalingMode : Qt::FastTransformation;
    return virtualCanvas.scaled(physicalSize, Qt::KeepAspectRatio, mode);
}
QImage DualCanvasRenderer::createVirtualCanvas(const RenderContext& context)
{
    QSize canvasSize = m_config.calculateVirtualCanvasSize();
    QImage canvas(canvasSize, QImage::Format_ARGB32_Premultiplied);
    canvas.fill(Qt::white); // A4白色背景
    QPainter painter(&canvas);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    // 渲染页面内容
    renderPageContent(painter, canvasSize, context);
    // 渲染页面装饰（如果启用）
    if (context.enablePageDecorations) {
        renderPageDecorations(painter, canvasSize, context);
    }
    painter.end();
    return canvas;
}
void DualCanvasRenderer::renderPageContent(QPainter& painter, const QSize& canvasSize,
                                         const RenderContext& context)
{
    if (context.sourceContent.isNull()) {
        return;
    }
    // 计算内容在画布中的位置
    QRect contentRect = calculateContentRect(context.sourceContent.size(), canvasSize);
    // 绘制内容
    painter.drawImage(contentRect, context.sourceContent);
}
void DualCanvasRenderer::renderPageDecorations(QPainter& painter, const QSize& canvasSize,
                                             const RenderContext& context)
{
    // 设置页码字体（相对于画布大小）
    QFont font = painter.font();
    int fontSize = qMax(8, canvasSize.height() / 100); // 画布高度的1%
    font.setPointSize(fontSize);
    painter.setFont(font);
    // 绘制页码（右下角）
    if (context.pageNumber > 0) {
        QString pageText = QString("%1").arg(context.pageNumber);
        if (context.totalPages > 0) {
            pageText = QString("%1 / %2").arg(context.pageNumber).arg(context.totalPages);
        }
        QRect pageNumRect(canvasSize.width() - 100, canvasSize.height() - 50, 80, 30);
        painter.setPen(Qt::black);
        painter.drawText(pageNumRect, Qt::AlignRight | Qt::AlignBottom, pageText);
    }
    // 可以在这里添加其他装饰：页眉、边框等
}
QRect DualCanvasRenderer::calculateContentRect(const QSize& contentSize, const QSize& canvasSize) const
{
    if (contentSize.isEmpty() || canvasSize.isEmpty()) {
        return QRect();
    }
    // 计算保持宽高比的内容区域
    double contentRatio = static_cast<double>(contentSize.width()) / contentSize.height();
    double canvasRatio = static_cast<double>(canvasSize.width()) / canvasSize.height();
    QSize scaledSize;
    if (contentRatio > canvasRatio) {
        // 内容更宽，以宽度为准
        scaledSize.setWidth(canvasSize.width());
        scaledSize.setHeight(qRound(canvasSize.width() / contentRatio));
    } else {
        // 内容更高，以高度为准
        scaledSize.setHeight(canvasSize.height());
        scaledSize.setWidth(qRound(canvasSize.height() * contentRatio));
    }
    // 居中放置
    QPoint topLeft(
        (canvasSize.width() - scaledSize.width()) / 2,
        (canvasSize.height() - scaledSize.height()) / 2
    );
    return QRect(topLeft, scaledSize);
}
QString DualCanvasRenderer::generateCacheKey(const RenderContext& context, double dpi) const
{
    QCryptographicHash hash(QCryptographicHash::Md5);
    // 添加影响渲染结果的关键参数
    hash.addData(QString("dpi_%1").arg(dpi).toUtf8());
    hash.addData(QString("page_%1").arg(context.pageNumber).toUtf8());
    hash.addData(QString("decorations_%1").arg(context.enablePageDecorations).toUtf8());
    // 添加内容的哈希（如果有）
    if (!context.sourceContent.isNull()) {
        hash.addData(QString("size_%1x%2").arg(context.sourceContent.width())
                                         .arg(context.sourceContent.height()).toUtf8());
    }
    return hash.result().toHex();
}
bool DualCanvasRenderer::hasCachedCanvas(const QString& cacheKey) const
{
    QMutexLocker locker(&m_cacheMutex);
    return m_virtualCanvasCache.contains(cacheKey) || m_physicalCanvasCache.contains(cacheKey);
}
QImage DualCanvasRenderer::getCachedCanvas(const QString& cacheKey) const
{
    QMutexLocker locker(&m_cacheMutex);
    // 优先从虚拟画布缓存获取
    if (m_virtualCanvasCache.contains(cacheKey)) {
        return *m_virtualCanvasCache[cacheKey];
    }
    // 其次从物理画布缓存获取
    if (m_physicalCanvasCache.contains(cacheKey)) {
        return *m_physicalCanvasCache[cacheKey];
    }
    return QImage();
}
void DualCanvasRenderer::setCachedCanvas(const QString& cacheKey, const QImage& canvas)
{
    if (canvas.isNull()) {
        return;
    }
    QMutexLocker locker(&m_cacheMutex);
    // 计算图像大小作为缓存成本
    int cost = canvas.sizeInBytes();
    // 根据DPI决定存储在哪个缓存中
    if (cacheKey.contains(QString("dpi_%1").arg(m_config.processingDpi))) {
        m_virtualCanvasCache.insert(cacheKey, new QImage(canvas), cost);
    } else {
        m_physicalCanvasCache.insert(cacheKey, new QImage(canvas), cost);
    }
}